package com.project_doctor.websocket;

// src/main/java/com/example/chatsystem/netty/WebSocketServerInitializer.java



import com.project_doctor.handler.WebSocketHandler;
import io.netty.channel.*;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.http.*;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import io.netty.handler.stream.ChunkedWriteHandler;
import io.netty.handler.timeout.IdleStateHandler;

import java.util.concurrent.TimeUnit;

public class WebSocketServerInitializer extends ChannelInitializer<SocketChannel> {

    private final String websocketPath;

    public WebSocketServerInitializer(String websocketPath) {
        this.websocketPath = websocketPath;
    }

    @Override
    protected void initChannel(SocketChannel ch) throws Exception {
        ChannelPipeline pipeline = ch.pipeline();

        // 添加HTTP编解码器和处理器
        pipeline.addLast(new HttpServerCodec());
        pipeline.addLast(new ChunkedWriteHandler());
        pipeline.addLast(new HttpObjectAggregator(65536));

        // 添加心跳检测
        pipeline.addLast(new IdleStateHandler(60, 0, 0, TimeUnit.SECONDS));

        // 添加请求分发处理器：区分HTTP请求和WebSocket请求
        pipeline.addLast(new HttpRequestHandler(websocketPath));

        // 添加WebSocket协议处理器，仅处理指定路径
        pipeline.addLast(new WebSocketServerProtocolHandler(websocketPath, null, true));

        // 添加自定义WebSocket处理器
        pipeline.addLast(new WebSocketHandler());
    }

    // 自定义HTTP请求处理器，用于分发请求
    private static class HttpRequestHandler extends SimpleChannelInboundHandler<FullHttpRequest> {

        private final String websocketPath;

        public HttpRequestHandler(String websocketPath) {
            this.websocketPath = websocketPath;
        }

        @Override
        protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest req) throws Exception {
            String uri = req.uri();

            // 放行Swagger和Knife4j相关请求，交给Spring处理
            if (isSwaggerOrKnife4jPath(uri)) {
                // 将请求传递给下一个处理器（最终由Spring处理）
                ctx.fireChannelRead(req.retain());
                return;
            }

            // 处理WebSocket升级请求
            if (websocketPath.equals(uri) && "websocket".equalsIgnoreCase(req.headers().get("Upgrade"))) {
                // 标记为WebSocket升级请求，继续处理
                ctx.fireChannelRead(req.retain());
                return;
            }

            // 其他HTTP请求返回404
            sendError(ctx, HttpResponseStatus.NOT_FOUND);
        }

        // 判断是否为Swagger或Knife4j路径
        private boolean isSwaggerOrKnife4jPath(String uri) {
            return uri.startsWith("/doc.html") ||        // Knife4j UI页面
                    uri.startsWith("/knife4j") ||         // Knife4j资源路径
                    uri.startsWith("/v2/api-docs") ||     // Swagger API文档
                    uri.startsWith("/swagger-resources") ||
                    uri.startsWith("/webjars");
        }

        // 发送错误响应
        private void sendError(ChannelHandlerContext ctx, HttpResponseStatus status) {
            FullHttpResponse response = new DefaultFullHttpResponse(
                    HttpVersion.HTTP_1_1, status, ctx.alloc().buffer());
            response.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/plain; charset=UTF-8");
            ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);
        }

        @Override
        public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
            cause.printStackTrace();
            ctx.close();
        }
    }
}